package com.junzhiit.nengji.app.service.impl;

import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.junzhiit.nengji.app.service.BankCardService;
import com.junzhiit.nengji.app.web.exception.BankCardExistException;
import com.junzhiit.nengji.app.web.exception.CheckFailException;
import com.junzhiit.nengji.app.web.exception.MobilePhoneCodeErrorException;
import com.junzhiit.nengji.app.web.exception.MobilePhoneCodeTimeoutException;
import com.junzhiit.nengji.app.web.exception.ShopNotFoundException;
import com.junzhiit.nengji.app.web.util.Constants;
import com.junzhiit.nengji.app.web.util.aliyun.BankUtil;
import com.junzhiit.nengji.app.web.util.aliyun.SmsUtil;
import com.junzhiit.nengji.app.web.util.aliyun.bean.BankData;
import com.junzhiit.nengji.app.web.vo.BankCardMobilePhoneVO;
import com.junzhiit.nengji.app.web.vo.BankCardVO;
import com.junzhiit.nengji.app.web.vo.PhoneCodeVO;
import com.junzhiit.nengji.app.web.vo.ResultVO;
import com.junzhiit.nengji.app.web.vo.SystemUserSessionVO;
import com.junzhiit.nengji.dao.BankCardDAO;
import com.junzhiit.nengji.dao.ShopDAO;
import com.junzhiit.nengji.dao.cache.BankCardCheckCountDAO;
import com.junzhiit.nengji.dao.cache.SystemUserCacheDAO;
import com.junzhiit.nengji.dao.util.DIYKey;
import com.junzhiit.nengji.model.BankCard;
import com.junzhiit.nengji.model.Shop;
import com.junzhiit.nengji.model.enums.BankCardType;
import com.junzhiit.nengji.model.enums.BankType;

@Service
public class BankCardServiceImpl extends BaseServiceImpl implements BankCardService {

	@Autowired
	private BankCardDAO bankCardDAO;
	
	@Autowired
	private SystemUserCacheDAO systemUserCacheDAO;
	
	@Autowired
	private ShopDAO shopDAO;
	
	@Autowired
	private BankCardCheckCountDAO bankCardCheckCountDAO;

	@Override
	public ResultVO findAll(String sessionId) {
		ResultVO result = new ResultVO();
		SystemUserSessionVO systemUserSessionVO = systemUserCacheDAO
				.getHash(DIYKey.getSessionHashKey(sessionId), SystemUserSessionVO.class);
		Shop shop = shopDAO.query(systemUserSessionVO.getSystemId());
		if (shop == null) {
			throw new ShopNotFoundException("店铺不存在");
		}
		
		result.setData(bankCardDAO.findAll(shop.getId()));
		
		return result;
	}
	
	@Override
	public ResultVO getMobilePhoneCode(BankCardMobilePhoneVO bankCardVO) {
		ResultVO result =new ResultVO();
		SystemUserSessionVO systemUserSessionVO = systemUserCacheDAO
				.getHash(DIYKey.getSessionHashKey(bankCardVO.getSessionId()), SystemUserSessionVO.class);
		BankCard bankCard = bankCardDAO.findByCardNumber(systemUserSessionVO.getSystemId(), bankCardVO.getBankCard());
		if(bankCard != null){
			throw new BankCardExistException("该银行卡已绑定，请更换银行卡！");
		}
		String smsModel=SmsUtil.ALIYUN_SMS_VALIDATION;
		String mobilePhone=bankCardVO.getMobilePhone();
		SmsUtil.sendPhoneCode(mobilePhone, smsModel);
		return result;
	}

	@Override
	public ResultVO check(BankCardVO bankCardVO) {
		ResultVO result = new ResultVO();
		
		PhoneCodeVO phoneCode = systemUserCacheDAO.getHash(DIYKey.getMobilePhoneCodeKey(bankCardVO.getMobilePhone()),
				PhoneCodeVO.class);
		if (!phoneCode.getCode().equals(bankCardVO.getCode())) {
			throw new MobilePhoneCodeErrorException("验证码不一致");
		}
		
		if (phoneCode.getTimestamp() < new Date().getTime()) {
			throw new MobilePhoneCodeTimeoutException("验证码已过期");
		}
		
		SystemUserSessionVO systemUserSessionVO = systemUserCacheDAO
				.getHash(DIYKey.getSessionHashKey(bankCardVO.getSessionId()), SystemUserSessionVO.class);
		BankCard bankCard = bankCardDAO.findByCardNumber(systemUserSessionVO.getSystemId(), bankCardVO.getBankCard());
		if(bankCard != null){
			throw new BankCardExistException("该银行卡已绑定，请更换银行卡！");
		}
		
		BankCardVO bank = new BankCardVO();
		String name = bankCardVO.getName();
		String number = bankCardVO.getBankCard();
		String idNumber = bankCardVO.getIdentityNumber();
		String mobilePhone = bankCardVO.getMobilePhone();
		BeanUtils.copyProperties(bankCardVO, bank);
		//减少检验次数
		String key = DIYKey.getBankCardCheckCount(systemUserSessionVO.getSystemId());
		String content = bankCardCheckCountDAO.getString(key);
		if(StringUtils.isNotBlank(content)){
			Integer count = Integer.valueOf(content);
			count = count-1;
			bankCardCheckCountDAO.addString(key, count.toString());
			bank.setCount(count);
		}
		BankData bankData = BankUtil.checkBank(number, name, idNumber, mobilePhone);
		if(bankData != null){
			bank.setBank(bankData.getBankName());
			bank.setBankType(bankData.getBankType());
			bank.setBankCode(bankData.getBankCode());
			bank.setBankKind(bankData.getBankKind());
		}else{
			throw new CheckFailException("验证银行卡失败！");
		}
		result.setData(bank);
		return result;
	}

	@Override
	public ResultVO add(BankCardVO bankCardVO) {
		ResultVO result = new ResultVO();
		BankCard bankCard = new BankCard();
		
		SystemUserSessionVO systemUserSessionVO = systemUserCacheDAO
				.getHash(DIYKey.getSessionHashKey(bankCardVO.getSessionId()), SystemUserSessionVO.class);
		
		BeanUtils.copyProperties(bankCardVO, bankCard);
		bankCard.setType(BankCardType.SHOP.toIntValue());
		bankCard.setShopId(systemUserSessionVO.getSystemId());
		bankCardDAO.insert(bankCard);
		return result;
	}

	@Override
	public void updateCheckCount() {
		String key = null;
		List<String> shopIds = bankCardDAO.findShopId();
		List<String> userIds = bankCardDAO.fingUserId();
		for(String shopId : shopIds){
			key = DIYKey.getBankCardCheckCount(shopId);
			bankCardCheckCountDAO.addString(key, Constants.CHECK_COUNT);
		}
		for(String userId : userIds){
			key = DIYKey.getBankCardCheckCount(userId);
			bankCardCheckCountDAO.addString(key, Constants.CHECK_COUNT);
		}
	}

	@Override
	public ResultVO checkCount(String sessionId) {
		ResultVO result = new ResultVO();
		SystemUserSessionVO systemUserSessionVO = systemUserCacheDAO
				.getHash(DIYKey.getSessionHashKey(sessionId), SystemUserSessionVO.class);
		String key = DIYKey.getBankCardCheckCount(systemUserSessionVO.getSystemId());
		String content = bankCardCheckCountDAO.getString(key);
		BankCardVO bank = new BankCardVO();
		if(StringUtils.isNotBlank(content)){
			Integer count = Integer.valueOf(content);
			bank.setCount(count);
		}
		result.setData(bank);
		return result;
	}

	@Override
	public ResultVO del(String bankCardId) {
		ResultVO result = new ResultVO();
		bankCardDAO.delete(bankCardId);
		return result;
	}

	@Override
	public ResultVO checkCompanyBank(BankCardVO bankCardVO) {
		ResultVO result = new ResultVO();
		SystemUserSessionVO systemUserSessionVO = systemUserCacheDAO
				.getHash(DIYKey.getSessionHashKey(bankCardVO.getSessionId()), SystemUserSessionVO.class);
		BankCard bankCard = bankCardDAO.findByCardNumber(systemUserSessionVO.getSystemId(), bankCardVO.getBankCard());
		if(bankCard != null){
			throw new BankCardExistException("该银行卡已绑定，请更换银行卡！");
		}
		BankCard bank=new BankCard();
		String acctName = bankCardVO.getCompanyName();
		String bankName = BankType.toStatus(bankCardVO.getBankLogo()).toStringText();
		String cardno = bankCardVO.getBankCard();
		BeanUtils.copyProperties(bankCardVO, bank);
		//减少检验次数
		String key = DIYKey.getBankCardCheckCount(systemUserSessionVO.getSystemId());
		String content = bankCardCheckCountDAO.getString(key);
		if(StringUtils.isNotBlank(content)){
			Integer count = Integer.valueOf(content);
			count = count-1;
			bankCardCheckCountDAO.addString(key, count.toString());
		}
		result= BankUtil.checkCompanyBank(acctName, bankName, cardno);
		if(result.getData() == null){
			bank.setType(BankCardType.SHOP.toIntValue());
			bank.setBank(bankName);
			bank.setShopId(systemUserSessionVO.getSystemId());
			bankCardDAO.insert(bank);
		}
		return result;
	}

	@Override
	public ResultVO checkAgain(BankCardVO bankCardVO) {
		ResultVO result = new ResultVO();
		SystemUserSessionVO systemUserSessionVO = systemUserCacheDAO
				.getHash(DIYKey.getSessionHashKey(bankCardVO.getSessionId()), SystemUserSessionVO.class);
		BankCard bank=new BankCard();
		BeanUtils.copyProperties(bankCardVO, bank);
		result = BankUtil.checkResult(bankCardVO.getRequestNo());
		if(result.getData() == null){
			bank.setType(BankCardType.SHOP.toIntValue());
			bank.setBank(BankType.toStatus(bankCardVO.getBankLogo()).toStringText());
			bank.setShopId(systemUserSessionVO.getSystemId());
			bankCardDAO.insert(bank);
		}
		return result;
	}
}
